#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>

/*
 * Jumper probe for vfs_mkdir.
 * Mirror principle enables access to arguments of the probed routine
 * from the probe handler.
 */

/* Proxy routine having the same arguments as actual vfs_mkdir() routine */
static int j_vfs_mkdir(struct inode* dir, struct dentry* dentry, umode_t mode)
{
    pr_info("dentry=%s\n", dentry->d_name.name);
}

static struct jprobe my_jprobe = {
    .entry = j_vfs_mkdir,
    .kp =
        {
            .symbol_name = "vfs_mkdir",
        },
};

static int __init jprobe_init(void)
{
    int ret;

    ret = register_jprobe(&my_jprobe);
    if (ret < 0) {
        pr_err("register_jprobe failed, returned %d\n", ret);
        return -1;
    }
    pr_info("Planted jprobe at %p, handler addr %p\n", my_jprobe.kp.addr,
            my_jprobe.entry);
    return 0;
}

static void __exit jprobe_exit(void)
{
    unregister_jprobe(&my_jprobe);
    pr_info("jprobe at %p unregistered\n", my_jprobe.kp.addr);
}

module_init(jprobe_init) module_exit(jprobe_exit) MODULE_LICENSE("GPL");